const PAGE_SIZE = 6;
const ITEM_HEIGHT = 100;





class RankListRenderer {
  constructor() {
    this.totalPage = 0;
    this.currPage = 0;
    this.init();
    this.userData = null;
    this.KVDataList = [];
    this.isShowRank = false;
    this.SCORE_NAME = "score";
    //1:powRank 2:levelRank
    this.gameDatas = [];
    this.powRankDatas = [];
    this.levRankDatas = [];
    this.curRankType = 1;
    this.isHasCashData = false;

    this.showType = 0;
  }

  init() {
    this.canvas = wx.getSharedCanvas();
    this.ctx = this.canvas.getContext('2d');
    this.ctx.imageSmoothingEnabled = true;
    this.ctx.imageSmoothingQuality = "high";
    // 
  }

  listen() {
    //msg -> {action, data}
    wx.onMessage(msg => {
      console.log("ranklist wx.onMessage", msg);
      switch (msg.action) {
        case "clearData":
          this.removeUserCloudStorage(["score"])
          break;
        case "preShowRank":
          this.preFetchFriendData(msg.data);
          break;
        case "showScoreRank":
          this.isShowRank = true;
          this.showType = 0;
          this.fetchPowFriendData(msg.data);
          break;
        case "hideFriend":
          this.isShowRank = false;
          break;
        case "page":
          console.log("page");
          if (!this.gameDatas.length) {
            return;
          }
          const delta = msg.data;
          const newPage = this.currPage + delta;
          if (newPage < 0) {
            console.log("已经是第一页了");
            return;
          }
          if (newPage + 1 > this.totalPage) {
            console.log("没有更多了");
            return;
          }
          this.currPage = newPage;
          var key = this.SCORE_NAME;
          this.showPagedRanks(newPage, key);
          break;
        case "setData":
          this.setData(msg.data);
          break;
        case "setSelfData":
          this.setSelfData(msg.data);
          break;
        case "showResultScoreRank":
          this.isShowRank = true;
          this.showType = 1;
          this.fetchPowFriendData(msg.data);
          break;
        default:
          console.log(`未知消息类型:msg.action=${msg.action}`);
          break;
      }
    });
  }

  getUserInfo(callback) {
    var callBackParams = {};
    var self = this;
    wx.getUserInfo({
      openIdList: ['selfOpenId'],
      success: (res) => {
        callback(res.data);
      },
      fail: (res) => {
        callback(null);
      }
    });
  }


  setSelfData(data) {
    this.userData = data;
  }
  setData(data) {
    var self = this;
    var setKVDataList = [];
    var reqKeyList = [];
    for (var what in data) {
      reqKeyList.push(what);
    }
    this.getUserCloudStorage(reqKeyList, function(KVDataList) {
      var obj;
      var currentValue;
      var objKey;
      var objValue;
      for (var what in data) {
        objKey = what;
        objValue = data[what];
        var len = KVDataList.length;
        var kvdata;
        var kvkey;
        var kvvalue;
        for (var i = 0; i < len; i++) {
          kvdata = KVDataList[i];
          if (kvdata.key == objKey && Number(objValue) <= Number(kvdata.value)) {
            objValue = kvdata.value;
          }
        }
        obj = {
          key: objKey,
          value: objValue + ""
        };
        setKVDataList.push(obj);
      }
      self.updateGameDatas(objValue)
      if (setKVDataList.length > 0) {
        self.setUserCloudStorage(setKVDataList);
      }
    });
  }

  dataSorter(gameDatas, field) {
    return gameDatas.sort((a, b) => {
      const kvDataA = a.KVDataList.find(kvData => kvData.key === field);
      const kvDataB = b.KVDataList.find(kvData => kvData.key === field);
      const gradeA = kvDataA ? parseInt(kvDataA.value || 0) : 0;
      const gradeB = kvDataB ? parseInt(kvDataB.value || 0) : 0;
      return gradeA > gradeB ? -1 : gradeA < gradeB ? 1 : 0;
    });
  }

  // 检查返回值是不是小于设置的大小
  checkKVDataList(data, KVDataList) {
    for (var i = 0; i < KVDataList.length; i++) {
      var curItem = KVDataList[i];
      var currentWeek = this.theWeek();
      var key = this.SCORE_NAME + "_" + currentWeek;
      if (curItem.key == key) {
        console.log(curItem.key)
        if (Number(data[this.SCORE_NAME]) >= Number(curItem.value)) {
          curItem.value = data[this.SCORE_NAME];
        }
      }
      if (curItem.key == ('max' + this.SCORE_NAME)) {
        if (Number(data[this.SCORE_NAME]) >= Number(curItem.value)) {
          curItem.value = data[this.SCORE_NAME];
        }
      }

      console.log('KVDataList', KVDataList)
    }
  }
  // 同步内存中最高分数据
  updateKVDataList(data) {
    var isInData = false;
    for (var i = 0; i < this.KVDataList.length; i++) {
      var curItem = this.KVDataList[i];
      if (curItem.key == data.key) {
        isInData = true
        if (Number(data.value) >= Number(curItem.value)) {
          curItem.value = data.value;
        }
      }
    }

    //如果没收数据就先存内存数据 
    if (!isInData) {
      this.KVDataList.push(data);
    }

  }
  // 同步内存中自己的排名中的最高分    
  updateGameDatas(fens) {
    var self = this;
    if (!self.userData) {
      self.getUserInfo((datas) => {
        console.log('updateGameDatas res')
        if (datas) {
          self.userData = datas[0];
          self.updateSelfGameDatas(fens);
        }
      })
    } else {
      self.updateSelfGameDatas(fens);
    }

  }


  setUserCloudStorage(KVDataList) {
    var self = this;
    console.log('setUserCloudStorage', KVDataList)
    wx.setUserCloudStorage({
      KVDataList: KVDataList,
      success: res => {
        console.log("wx.setUserCloudStorage success", res);
        //this.setData(this.lastSendData);                
      },
      fail: res => {
        console.log("wx.setUserCloudStorage fail", res);
      }
    })

  }

  updateSelfGameDatas(fens) {
    if (!this.gameDatas) return;
    for (var i = 0; i < this.gameDatas.length; i++) {
      var curUserData = this.gameDatas[i];
      if (this.userData.nickName == curUserData.nickname && this.userData.avatarUrl == curUserData.avatarUrl) {
        var curKVDataList = curUserData.KVDataList;
        for (var j = 0; j < curKVDataList.length; j++) {
          var curValue = curKVDataList[j]
          var curPro = this.SCORE_NAME
          if (curValue.key == curPro) {
            if (Number(fens) >= Number(curValue.value)) {
              curValue.value = fens;
            }
          }
        }
      }
    }
    this.gameDatas = this.dataSorter(this.gameDatas, this.SCORE_NAME);
  }

  // 找回自己排名位置
  findSelfDataIndex() {
    for (var i = 0; i < this.gameDatas.length; i++) {
      var curUserData = this.gameDatas[i];
      if (this.userData.nickName == curUserData.nickname && this.userData.avatarUrl == curUserData.avatarUrl) {
        return i;
      }
    }
    return -1;
  }


  getUserCloudStorage(keyList, callBack) {
    wx.getUserCloudStorage({
      keyList: keyList,
      success: res => {
        console.log("wx.getUserCloudStorage success", res);
        callBack(res.KVDataList);
      },
      fail: res => {
        console.log("wx.getGroupCloudStorage fail", res);
      }
    })
  }

  removeUserCloudStorage(keyList) {
    wx.removeUserCloudStorage({
      keyList: keyList,
      success: res => {
        //console.log("wx.removeUserCloudStorage success", res);                
      },
      fail: res => {
        //console.log("wx.removeUserCloudStorage fail", res);
      }
    })
  }

  preFetchFriendData(key) {
    var self = this;
    wx.getFriendCloudStorage({
      keyList: [
        key,
      ],
      success: res => {
        self.isHasCashData = true;
        var data = this.removeInvaildData(res.data);
        const dataLen = data.length;
        if (dataLen) {

          var curKVDataList;
          for (var i = 0; i < data.length; i++) {
            curKVDataList = data[i].KVDataList;
            break;
          }
          var curKey = '';
          if (curKVDataList && curKVDataList.length) {
            curKey = curKVDataList[0].key;
          }
          if (curKey == this.SCORE_NAME) {
            this.powRankDatas = this.dataSorter(data, key);
            this.gameDatas = this.getCloneDatas(this.powRankDatas);
          }
          this.currPage = 0;
          this.totalPage = Math.ceil(dataLen / PAGE_SIZE);
          //test
          //this.totalPage =2
        }

      },
      fail: res => {
        console.log("wx.getFriendCloudStorage fail", res);
      },
    });
  }


  fetchPowFriendData(key) {
    var self = this;
    var cashKey = '';
    console.log("isHasCashData:", this.isHasCashData);
    if (this.powRankDatas.length <= 0) {
      this.isHasCashData = false;
    }
    // if (this.isHasCashData) {
    //     //使用缓存数据            
    //     this.currPage = 0;
    //     this.totalPage = Math.ceil(this.gameDatas.length / PAGE_SIZE);
    //     this.showPagedRanks(0, key);
    // } else {
    wx.getFriendCloudStorage({
      keyList: [
        key,
      ],
      success: res => {
        self.isHasCashData = true;
        var data = this.removeInvaildData(res.data);
        console.log(data);
        const dataLen = data.length;
        if (dataLen) {

          var curKVDataList;
          for (var i = 0; i < data.length; i++) {
            curKVDataList = data[i].KVDataList;
            break;
          }
          var curKey = '';
          if (curKVDataList && curKVDataList.length) {
            curKey = curKVDataList[0].key;
          }
          console.log(curKey)
          if (curKey == this.SCORE_NAME) {
            this.powRankDatas = this.dataSorter(data, key);
            this.gameDatas = this.getCloneDatas(this.powRankDatas);
            console.log(this.gameDatas)
          }

          this.currPage = 0;
          this.totalPage = Math.ceil(dataLen / PAGE_SIZE);
          //test
          // this.totalPage =2
          this.showPagedRanks(0, key);
        }

      },
      fail: res => {
        console.log("wx.getFriendCloudStorage fail", res);
      },
    });
    // }
  }


  removeInvaildData(data) {
    var result = [];
    var len = data.length;
    for (var i = 0; i < len; i++) {
      if (data[i].KVDataList.length > 0) {
        result.push(data[i]);
      }
    }
    console.log(result);
    return result;
  }


  getCloneDatas(srcDatas) {
    var result = []
    var testLen = srcDatas.length;
    // srcDatas.length;
    // testLen = 10
    for (var i = 0; i < testLen; i++) {
      var item = {
        avatarUrl: '',
        nickname: '',
        openid: '',
        KVDataList: []
      }
      var curSrcData = srcDatas[i];
      item.avatarUrl = curSrcData.avatarUrl;
      item.nickname = curSrcData.nickname;
      item.openid = curSrcData.openid;
      for (var j = 0; j < curSrcData.KVDataList.length; j++) {
        var curValue = curSrcData.KVDataList[j];
        var subItem = {
          key: curValue.key,
          value: curValue.value
        };
        item.KVDataList.push(subItem);
      }
      result.push(item)
    }
    return result;
  }


  showPagedRanks(page, key) {
    const pageStart = page * PAGE_SIZE;
    const pagedData = this.gameDatas.slice(pageStart, pageStart + PAGE_SIZE);
    const pageLen = pagedData.length;

    this.ctx.clearRect(0, 0, 1000, 1000);
    var leng = 0;
    if (this.showType == 0) {
      leng = pagedData.length;
    }
    if (this.showType == 1) {
      leng = pagedData.length > 3 ? 3 : pagedData.length;
    }

    for (let i = 0, len = leng; i < len; i++) {
      if (this.showType == 0) {
        this.drawRankItem(this.ctx, i, pageStart + i + 1, pagedData[i], pageLen, key);
      } else if (this.showType == 1) {
        this.drawRankTypeItem(this.ctx, i, pageStart + i + 1, pagedData[i], pageLen, key);
      }

    }


    //this.isDrawNotice(this.ctx);        
  }


  drawRankTypeItem(ctx, index, rank, data, pageLen, key) {
    const avatarUrl = data.avatarUrl;
    const nick = data.nickname;
    const kvData = data.KVDataList.find(kvData => kvData.key === key);
    const grade = kvData ? kvData.value : 0;
    const itemGapX = 200 * index;
    //背景
    //分隔线
    // const bgImg = wx.createImage();
    // bgImg.src = 'Leaderboard/res/rankbg.png';
    // bgImg.onload = () => {
    //  ctx.drawImage(bgImg, 10, itemGapY + 15, 540, 88);
    //名次
    var rankColor = "#c64710";
    var rankSrc = "";

    // switch (rank) {
    //     case 1:
    //         rankColor = "#ff4343";
    //         rankSrc = 'Leaderboard/res/No1.png';
    //         break;
    //     case 2:
    //         rankColor = "#206dd5";
    //         rankSrc = 'Leaderboard/res/No2.png';
    //         break;
    //     case 3:
    //         rankColor = "#0dac2f";
    //         rankSrc = 'Leaderboard/res/No3.png';
    //         break;
    // }

    // if (rank <= 3) {
    //     //头像
    //     const rankImg = wx.createImage();
    //     rankImg.src = rankSrc;
    //     rankImg.onload = () => {
    //         ctx.drawImage(rankImg, 32, 18 + itemGapY, 41, 85);
    //     };

    // } else {
    ctx.fillStyle = rankColor;
    ctx.textAlign = "center";
    ctx.baseLine = "middle";
    ctx.font = "34px Helvetica";
    ctx.fillText("第" + rank + "名", 150 + itemGapX, 50, 100);
    // }



    //头像
    const avatarImg = wx.createImage();
    avatarImg.src = avatarUrl;
    avatarImg.onload = () => {
      if (index + 1 > pageLen) {
        return;
      }
      ctx.drawImage(avatarImg, 100 + itemGapX, 76, 100, 100);
    };

    //名字
    ctx.fillStyle = "#FFFFFF";
    ctx.textAlign = "center";
    ctx.baseLine = "middle";
    ctx.font = "30px Helvetica";
    ctx.fillText(this.filterName(nick), 150 + itemGapX, 220, 100);

    //分数
    ctx.fillStyle = "#EEAF28";
    ctx.textAlign = "center";
    ctx.baseLine = "middle";
    ctx.font = "30px Helvetica";
    var curValue = grade;
    // if (this.curRankType == 1) {
    //     var curValues = grade.split('|');
    //     curValue = '' + curValues[0] + this.uintToString(curValues[1]) + '/s'
    // } else {
    //     curValue = '' + grade.toString() + " 关"
    // }
    ctx.fillText(`${curValue}`, 150 + itemGapX, 270, 100);
    // };
  }

  filterName(curValue) {
    var result = '';
    var len = 0;
    for (var i = 0; i < curValue.length; i++) {
      var c = curValue.charCodeAt(i);
      //单字节加1 
      if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
        len++;
      } else {
        len += 2;
      }
      if (len <= 8) {
        result += curValue.substr(i, 1);
      }
    }
    return result;
  }

  isDrawNotice(ctx) {
    if (this.gameDatas.length > 1) return;
    if (this.gameDatas.length == 1) {
      var curUserData = this.gameDatas[0];
      if (this.userData.nickName != curUserData.nickname || this.userData.avatarUrl != curUserData.avatarUrl) {
        //不是自己
        return;
      }
    }
    this.drawRankNoticeItem(ctx);
  }

  //canvas原点在左上角
  drawRankNoticeItem(ctx, gameDatas) {
    ctx.fillStyle = "#777063";
    ctx.textAlign = "center";
    ctx.baseLine = "middle";
    ctx.font = "35px Helvetica";
    ctx.fillText(`没有好友正在玩，快去邀请他们吧!`, 320, 400);
  }

  createImage(ctx, data) {
    const itemImg = wx.createImage();
    itemImg.src = data.imgSrc;
    itemImg.onload = () => {
      ctx.drawImage(itemImg, data.x, data.y, data.width, data.height);
    };
  }


  //canvas原点在左上角
  drawRankItem(ctx, index, rank, data, pageLen, key) {
    const avatarUrl = data.avatarUrl;
    const nick = data.nickname;
    const kvData = data.KVDataList.find(kvData => kvData.key === key);
    const grade = kvData ? kvData.value : 0;
    const itemGapY = ITEM_HEIGHT * index;
    //背景
    //分隔线
    const bgImg = wx.createImage();
    bgImg.src = 'Leaderboard/res/rankbg.png';
    bgImg.onload = () => {
      if (index + 1 > pageLen) {
        return;
      }
      ctx.drawImage(bgImg, 10, itemGapY + 15, 540, 88);
      //名次
      var rankColor = "#0b7540";
      var rankSrc = "";

      // switch (rank) {
      //     case 1:
      //         rankColor = "#ff4343";
      //         rankSrc = 'Leaderboard/res/No1.png';
      //         break;
      //     case 2:
      //         rankColor = "#206dd5";
      //         rankSrc = 'Leaderboard/res/No2.png';
      //         break;
      //     case 3:
      //         rankColor = "#0dac2f";
      //         rankSrc = 'Leaderboard/res/No3.png';
      //         break;
      // }

      // if (rank <= 3) {
      //     //头像
      //     const rankImg = wx.createImage();
      //     rankImg.src = rankSrc;
      //     rankImg.onload = () => {
      //         ctx.drawImage(rankImg, 32, 18 + itemGapY, 41, 85);
      //     };

      // } else {
      ctx.fillStyle = rankColor;
      ctx.textAlign = "center";
      ctx.baseLine = "middle";
      ctx.font = "40px Helvetica";
      ctx.fillText(`${rank}`, 62, 70 + itemGapY, 100);
      // }



      //头像
      const avatarImg = wx.createImage();
      avatarImg.src = avatarUrl;
      avatarImg.onload = () => {
        if (index + 1 > pageLen) {
          return;
        }
        ctx.drawImage(avatarImg, 130, 26 + itemGapY, 64, 64);
      };

      //名字
      ctx.fillStyle = "#FF0000";
      ctx.textAlign = "left";
      ctx.baseLine = "middle";
      ctx.font = "24px Helvetica";
      ctx.fillText(this.filterName(nick), 220, 70 + itemGapY);

      //提示
      ctx.fillStyle = "#FF0000";
      ctx.textAlign = "left";
      ctx.baseLine = "middle";
      ctx.font = "24px Helvetica";
      var NoticeValue = '得分:'
      ctx.fillText(`${NoticeValue}`, 400, 70 + itemGapY);

      //分数
      ctx.fillStyle = "#FF0000";
      ctx.textAlign = "left";
      ctx.baseLine = "middle";
      ctx.font = "24px Helvetica";
      var curValue = grade;
      // if (this.curRankType == 1) {
      //     var curValues = grade.split('|');
      //     curValue = '' + curValues[0] + this.uintToString(curValues[1]) + '/s'
      // } else {
      //     curValue = '' + grade.toString() + " 关"
      // }
      ctx.fillText(`${curValue}`, 460, 70 + itemGapY);
    };
  }

  filterName(curValue) {
    var result = '';
    var len = 0;
    for (var i = 0; i < curValue.length; i++) {
      var c = curValue.charCodeAt(i);
      //单字节加1 
      if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
        len++;
      } else {
        len += 2;
      }
      if (len <= 8) {
        result += curValue.substr(i, 1);
      }
    }
    return result;
  }

  isDrawNotice(ctx) {
    if (this.gameDatas.length > 1) return;
    if (this.gameDatas.length == 1) {
      var curUserData = this.gameDatas[0];
      if (this.userData.nickName != curUserData.nickname || this.userData.avatarUrl != curUserData.avatarUrl) {
        //不是自己
        return;
      }
    }
    this.drawRankNoticeItem(ctx);
  }

  //canvas原点在左上角
  drawRankNoticeItem(ctx, gameDatas) {
    ctx.fillStyle = "#777063";
    ctx.textAlign = "center";
    ctx.baseLine = "middle";
    ctx.font = "35px Helvetica";
    ctx.fillText(`没有好友正在玩，快去邀请他们吧!`, 320, 400);
  }

  createImage(ctx, data) {
    const itemImg = wx.createImage();
    itemImg.src = data.imgSrc;
    itemImg.onload = () => {
      ctx.drawImage(itemImg, data.x, data.y, data.width, data.height);
    };
  }


  uintToString(index) {
    /**根据单位换算 index [ 1:个位 2:k 3:m 4:b 5:t 6:q] */
    index = parseInt(index);
    if (index < 2) return '';
    index = index - 1;
    var saveLet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var totalLen = saveLet.length;
    var singleLet = '';
    var val = 0;
    while (index > 0) {
      val = (index - 1) % 26;
      singleLet = saveLet[val] + singleLet;
      index = Math.floor((index - 1) / totalLen);
    }
    return singleLet;
  }
}

const rankList = new RankListRenderer();
rankList.listen();